﻿using System;
using System.Collections.Generic;
using System.Drawing;
using System.Text;
using System.Threading;
using System.Windows.Forms;

namespace ThreadPool
{
    public partial class MainForm : Form
    {
        public MainForm()
        {
            InitializeComponent();
        }

        private void btnOrder_Click(object sender, EventArgs e)
        {
            if (string.IsNullOrEmpty(tbName.Text))
            {
                MessageBox.Show("请您先输入姓名！", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
            }

            BeginAnOrder(tbName.Text);

            var idx = new Random().Next() % names.Count;
            tbName.Text = names[idx];
        }


        int id = 0;
        StringBuilder sb = new StringBuilder();
        void Log(int No, string log)
        {
            var str = 
                $"{DateTime.Now.ToString("HH:mm:ss")} - " +
                $"{log}，NO:{No}\r\n";
            AutoInvoke(() =>
            {
                tbLogs.AppendText(str);
            });
        }


        void BeginAnOrder(string name)
        {
            var orderNo = ++id;
            System.Threading.ThreadPool.QueueUserWorkItem(
                BeginMake, new Customer(orderNo) { Name = name });
        }

        void BeginMake(object state)
        {
            var c = state as Customer;
            if (c != null)
            {
                Log(c.No, $"顾客 {c.Name} 热干面一碗");
                HLStep(pbOrder);

                AutoInvoke(() => lbListCus.Items.Add(c));

                HLStep(pbCash);

                var cashM = c.No % 2 == 0 ? tbCash1 : tbCash2;
                Log(c.No, $"{c.Name} 缴费，{cashM.Text}");

                HLStep(cashM, 2000, c.No);

                HLStep(pbBegin);

                var order = new Order(c);
                AutoInvoke(() => lbOrders.Items.Add(order));

                HLStep(pbToMan);

                Log(c.No, $"{tbFirstMan.Text} 煮面");

                lock (lbOrders)
                {
                    AutoInvoke(() => lbOrders.Items.Remove(order));
                    HLStep(tbFirstMan, 3000, c.No);
                }

                System.Threading.ThreadPool.QueueUserWorkItem(
                    Boil, new Noodle(c));
            }
        }

        void Boil(object n)
        {
            var nd = n as Noodle;

            HLStep(pbBoil);

            Log(nd.No, $"{nd.Name} 的面条下锅");
            AutoInvoke(()=>
            {
                lbNoodles.Items.Add(nd);
            });

            Thread.Sleep(10000);

            AutoInvoke(() =>
            {
                lbNoodles.Items.Remove(nd);
            });
                                    
            Log(nd.No, $"{nd.Name} 的面条出锅");
            HLStep(pbMake);
            Log(nd.No, $"开始制作 {nd.Name} 的热干面");
            HLStep(tbSecond, 3000, nd.No);

            Log(nd.No, $"{nd.Name} 的热干面 制作完成");
            HLStep(pbFinish);

            var msg = $"请 {nd.Name} 取餐";
            Log(nd.No, msg);
            AutoInvoke(() =>
            {
                lbOkNoodles.Items.Add(nd);
            });

            var waitTime = (new Random().Next() % 5 + 1) * 1000;

            Thread.Sleep(waitTime);
            Log(nd.No, $"{nd.Name} 取餐完成");
            AutoInvoke(() =>
            {
                lbListCus.Items.Remove(nd.Cus);
                lbOkNoodles.Items.Remove(nd);
            });
        }

        void HLStep(PictureBox pb)
        {
            AutoInvoke(() =>
            {
                pb.Image = Properties.Resources.down2;
            });
            Thread.Sleep(1000);
            AutoInvoke(() =>
            {
                pb.Image = Properties.Resources.down1;
            });
        }

        void HLStep(TextBox tb, int time, int no)
        {
            lock (tb)
            {
                Thread.Sleep(500);
                var ot = tb.Text;
                var oc = SystemColors.Control;
                AutoInvoke(() =>
                {
                    tb.BackColor = Color.Red;
                    tb.Text = ot + $"(NO:{no})";
                });
                Thread.Sleep(time);
                AutoInvoke(() =>
                {
                    tb.BackColor = oc;
                    tb.Text = ot;
                });
            }
        }

        private void chkAuto_CheckedChanged(object sender, EventArgs e)
        {
            timerAuto.Enabled = chkAuto.Checked;
        }

        IList<string> names = new List<string>() { "小姐姐", "小明", "小红", "小王", "小魏", "小张" };

        private void timerAuto_Tick(object sender, EventArgs e)
        {
            Random rd = new Random();
            var idx = rd.Next() % names.Count;
            BeginAnOrder(names[idx]);
        }



        void AutoInvoke(Action action)
        {
            if (this.InvokeRequired)
            {
                this.Invoke(action);
            }
            else
            {
                action.Invoke();
            }
        }

        class Customer
        {
            public Customer(int no)
            {
                No = no;
            }

            public int No { get; private set; }
            public string Name { get; set; }

            public override string ToString()
            {
                return $"{Name}(NO:{No})";
            }
        }
        class Order
        {
            Customer _c;
            public Order(Customer c)
            {
                _c = c;
            }

            public override string ToString()
            {
                return $"{_c.Name} 的订单(NO:{_c.No})";
            }
        }
        class Noodle
        {
            Customer _c;
            public Noodle(Customer c)
            {
                _c = c;
            }

            public override string ToString()
            {
                return $"{_c.Name} 的热干面(NO:{_c.No})";
            }

            public Customer Cus => _c;
            public int No => _c.No;

            public string Name => _c.Name;
        }

    }
}
